package com.nami.ucenter.application.dubbo;


import cn.hutool.core.collection.CollUtil;
import com.nami.basic.dto.MultiResponse;
import com.nami.basic.dto.Response;
import com.nami.basic.dto.SingleResponse;
import com.nami.gate.external.basic.cache.user.DeviceInfo;
import com.nami.gate.external.basic.cache.user.UserDeviceRel;
import com.nami.ucenter.application.dubbo.convertor.UserConvert;
import com.nami.ucenter.application.dubbo.convertor.UserModelToUserDTOAssembler;
import com.nami.ucenter.client.api.UserReadClient;
import com.nami.ucenter.client.request.UserDeviceDelCmd;
import com.nami.ucenter.client.response.UserDTO;
import com.nami.ucenter.client.response.UserWithDeviceInfoDTO;
import com.nami.ucenter.domain.model.UserModel;
import com.nami.ucenter.domain.port.repository.UserRepository;
import com.nami.ucenter.domain.service.DeviceLogoutDomainService;
import com.nami.ucenter.domain.service.UserDomainService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.dromara.common.core.utils.StringUtils;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@DubboService
@RequiredArgsConstructor
public class UserReadClientImpl implements UserReadClient {

    private final UserRepository userRepository;
    private final UserDomainService userDomainService;
    private final DeviceLogoutDomainService logoutDomainService;


    @Override
    public SingleResponse<UserDTO> getByUserId(String appKey, String userId) {
        if (StringUtils.isBlank(appKey) || StringUtils.isBlank(userId)) {
            return SingleResponse.buildFailure("400", "参数不正确！");
        }
        UserModel userModel = userRepository.find(appKey, userId);
        return SingleResponse.of(UserModelToUserDTOAssembler.toDTO(userModel));
    }

    @Override
    public MultiResponse<UserDTO> listByUserIds(List<String> userIds) {
        if (userIds == null || userIds.isEmpty()) {
            return MultiResponse.buildFailure("400", "参数不正确！");
        }
        List<UserModel> users = userRepository.listByUserIds(userIds);
        return MultiResponse.of(UserModelToUserDTOAssembler.toDTOs(users));
    }

    @Override
    public SingleResponse<UserDTO> getByUserId(String userId) {
        throw new UnsupportedOperationException();
    }

    @Override
    public SingleResponse<Map<String, UserDTO>> mapByUserIds(List<String> userIds) {
        if (userIds == null || userIds.isEmpty()) {
            return SingleResponse.buildFailure("400", "参数不正确！");
        }
        List<UserModel> users = userRepository.listByUserIds(userIds);
        List<UserDTO> list = UserModelToUserDTOAssembler.toDTOs(users);
        if (CollUtil.isEmpty(list)) {
            return SingleResponse.of(Collections.emptyMap());
        }
        Map<String, UserDTO> result = list.stream()
            .collect(Collectors.toMap(UserDTO::getUserId, Function.identity()));
        return SingleResponse.of(result);
    }

    @Override
    public SingleResponse<UserDTO> getByMobile(String mobile) {
        throw new UnsupportedOperationException();
    }

    @Override
    public SingleResponse<UserDTO> getByAccount(String account) {
        throw new UnsupportedOperationException();
    }

    @Override
    public SingleResponse<UserWithDeviceInfoDTO> getUserInfoFromCacheOrDB(String appKey, String userId) {
        if (StringUtils.isBlank(appKey) || StringUtils.isBlank(userId)) {
            return SingleResponse.buildFailure("400", "参数丢失");
        }

        UserDeviceRel user = userDomainService.getUserInfoFromCacheOrDB(appKey, userId);
        UserWithDeviceInfoDTO dto = UserConvert.INSTANCE.convert2(user);
        return SingleResponse.of(dto);
    }

    @Override
    public Response removeOfflineDevice(UserDeviceDelCmd request) {
        boolean result = logoutDomainService.terminateUserSession(request.getAppKey(), request.getUserId(), request.getInstanceId());
        if (!result) {
            Response.buildFailure("500", "系统错误！");
        }
        return Response.buildSuccess();
    }

    @Override
    public MultiResponse<DeviceInfo> getOnlDevices(String appKey, String userId) {
        List<DeviceInfo> deviceInfos = userDomainService.getOnlDevices(appKey, userId);
        return MultiResponse.of(deviceInfos);
    }

    @Override
    public MultiResponse<UserDeviceRel> listUsersWithAttachedDevicesWhenOnline(String appKey, List<String> userIds) {
        if (StringUtils.isBlank(appKey) || CollUtil.isEmpty(userIds)) {
            return MultiResponse.buildFailure("400", "参数丢失");
        }
        List<UserDeviceRel> result = userDomainService.listUsersWithAttachedDevicesWhenOnline(appKey, userIds);
        return MultiResponse.of(result);
    }

}
